<?php

/*
	Class: Communitas_Integrate_Model_Catalog_Category_Api

	About: Authors
		Tyler Vigeant, Rich Joslin, Swift Collective

	About: License
		<http://communit.as/docs/license>
*/
class Communitas_Integrate_Model_Catalog_Category_Api extends Mage_Catalog_Model_Category_Api {

	/*
		Function: __construct
	*/
	public function __construct() {
		parent::__construct();
	}

	/*
		Function: level

		Returns: array
	*/
	public function level($website = null, $store = null, $categoryId = null) {
		return parent::level($website, $store, $categoryId);
	}

	/*
		Function: tree

		Returns: array
	*/
	public function tree($parentId = null, $store = null) {
		$tree = Mage::getResourceSingleton('catalog/category_tree')->load();

		if (is_null($parentId) && !is_null($store)) {
			$parentId = Mage::app()->getStore($this->_getStoreId($store))->getRootCategoryId();
		} elseif (is_null($parentId)) {
			$parentId = 1;
		}

		$tree = Mage::getResourceSingleton('catalog/category_tree')->load();

		$root = $tree->getNodeById($parentId);

		if ($root && $root->getId() == 1) {
			$root->setName(Mage::helper('catalog')->__('Root'));
		}

		$collection = Mage::getModel('catalog/category')->getCollection()
			->setStoreId($this->_getStoreId($store))
			->addAttributeToSelect('name')
			->addAttributeToSelect('url_key')
			->addAttributeToSelect('is_active')
			->addAttributeToSelect('is_anchor')
			->addAttributeToSelect('blackdiamond_swiftcollective_cat_is_hidden')
			->addAttributeToSelect('blackdiamond_swiftcollective_cat_is_kit');

		$tree->addCollectionData($collection, true);

		return $this->_nodeToArray($root);
	}

	/*
		Function: getKits

		Returns: array
	*/
/*
	function getKits($store = null) {
		$collection = Mage::getModel('catalog/category')->getCollection();
		$collection->setStoreId($this->_getStoreId($store));
		$collection->addAttributeToFilter('blackdiamond_swiftcollective_cat_is_kit', 1);
		$collection->addAttributeToSelect('name');
		$collection = $collection->load();
		$results = array();
		foreach ($collection as $kit) {
			$results[] = array(
				'name' => $kit->getName(),
			);
		}
		return $results;
	}
*/

	/*
		Function: _nodeToArray

		Returns: array
	*/
	protected function _nodeToArray(Varien_Data_Tree_Node $node) {
		$result = array();
		$result['is_hidden']      = $node->getBlackdiamondSwiftcollectiveCatIsHidden();
		$result['is_kit']      = $node->getBlackdiamondSwiftcollectiveCatIsKit();
		$result['category_id'] = $node->getId();
		$result['url_key']     = $node->getUrlKey();
		$result['parent_id']   = $node->getParentId();
		$result['name']        = $node->getName();
		$result['is_active']   = $node->getIsActive();
		$result['is_anchor']   = $node->getIsAnchor();
		$result['position']    = $node->getPosition();
		$result['level']       = $node->getLevel();
		// $result['modified_at'] = $node->getModifiedAtDate();
		$result['children']    = array();
		foreach ($node->getChildren() as $child) {
			$new_child = $this->_nodeToArray($child);
			// FILTER OUT HIDDEN CATEGORIES
			if ($new_child['is_hidden'] != 1) {
				$result['children'][] = $new_child;
			}
		}
		return $result;
	}

	/*
		Function: _initCategory

		Returns: Mage_Catalog_Model_Category
	*/
	protected function _initCategory($categoryId, $store = null) {
		return parent::_initCategory($categoryId, $store);
	}

	/*
		Function: info

		Returns: array
	*/
	public function info($categoryId, $store = null, $attributes = null) {
        $category = $this->_initCategory($categoryId, $store);

        // Basic category data
        $result = array();
        $result['category_id'] = $category->getId();

        $result['is_active']   = $category->getIsActive();
        $result['position']    = $category->getPosition();
        $result['level']       = $category->getLevel();

        foreach ($category->getAttributes() as $attribute) {
            if ($this->_isAllowedAttribute($attribute, $attributes)) {
                $result[$attribute->getAttributeCode()] = $category->getData($attribute->getAttributeCode());
            }
        }
        $result['parent_id']   = $category->getParentId();
        $result['children']           = $category->getChildren();
        $result['all_children']       = $category->getAllChildren();

        return $result;
	}

	/*
		Function: getfilters
	*/
	public function getfilters($categoryId, $store = null) {
		$store = $this->_getStoreId($store);

		$collection = Mage::getModel('catalog/product')->getCollection()
			->setStoreId($store)
			->addFieldToFilter('category_ids', array($categoryId))
			->addAttributeToSelect('*');

		$set_info = array();
		$filterable_attributes = array();

		foreach ($collection as $product) {
			$setId = $product->getAttributeSetId();

			if (!array_key_exists($setId, $set_info)) {
				$set_info[$setId] = Mage::getModel('catalog/product')->getResource()->loadAllAttributes()->getSortedAttributes($setId);
			}

			foreach ($set_info[$setId] as $attribute) {
				if ((!$attribute->getId() || $attribute->isInSet($setId)) && $this->_isAllowedAttribute($attribute)) {
					if ($attribute->getIsFilterable() && $attribute->usesSource()) {
						$code = $attribute->getAttributeCode();
						if (!array_key_exists($code, $filterable_attributes)) {
							$filterable_attributes[ $code ]['name'] = $attribute->getFrontendLabel();
							$filterable_attributes[ $code ]['options'] = Mage::getResourceModel('eav/entity_attribute_option_collection')
																							 ->setAttributeFilter( $attribute->getId() )
																							 ->setStoreFilter($store)
																							 ->load()
																							 ->toOptionArray();
						}

						foreach ($filterable_attributes[ $code ]['options'] as $key => $option) {
							if ($filterable_attributes[$code]['options'][$key]['used'] == true) {
								continue;	
							}
							$methodname = "get".str_replace(' ','',ucwords(str_replace('_',' ',$code)));
							if ($product->$methodname() == $filterable_attributes[$code]['options'][$key]['value']) {
								$filterable_attributes[$code]['options'][$key]['used'] = true;
							} else {
								$filterable_attributes[$code]['options'][$key]['used'] = false;
							}
						}
					}
				}
			}
		}
		foreach ($filterable_attributes as $code => $value) {
			foreach ($value['options'] as $key => $info) {
				if (!$info['used']) {
					unset($filterable_attributes[$code]['options'][$key]);
				} else {
					unset($filterable_attributes[$code]['options'][$key]['used']);
				}
			}
		}
		return $filterable_attributes;
	}

	/*
		Function: create

		Returns: int
	*/
	public function create($parentId, $categoryData, $store = null) {
		return parent::create($parentId, $categoryData, $store);
	}

	/*
		Function: update

		Returns: boolean
	*/
	public function update($categoryId, $categoryData, $store = null) {
		$category = $this->_initCategory($categoryId, $store);
		foreach ($category->getAttributes() as $attribute) {
			$attribute_code = $attribute->getAttributeCode();
			if ($this->_isAllowedAttribute($attribute) && isset($categoryData[$attribute_code])) {
				$category->setData($attribute_code, $categoryData[$attribute_code]);
			}
		}
		try {
			$category->save();
		} catch (Mage_Core_Exception $e) {
			$this->_fault('data_invalid', $e->getMessage());
		}
		return true;
	}

	/*
		Function: move

		Returns: boolean
	*/
	public function move($categoryId, $parentId, $afterId = null) {
		return parent::move($categoryId, $parentId, $afterId);
	}

	/*
		Function: delete
	*/
	public function delete($categoryId) {
		if ((int)$categoryId <= 0) {
			return false;
		} else {
			return parent::delete($categoryId);
		}
	}

	/*
		Function: _getProductId

		Returns: int
	*/
	protected function _getProductId($productId) {
		return parent::_getProductId($productId);
	}

	/*
		Function: assignedProducts

		Returns: array
	*/
	public function assignedProducts($categoryId) {
		return parent::assignedProducts($categoryId);
	}

	/*
		Function: assignProduct

		Returns: boolean
	*/
	public function assignProduct($categoryId, $productId, $position = null) {
		return parent::assignProduct($categoryId, $productId, $position);
	}

	/*
		Function: updateProduct

		Returns: boolean
	*/
	public function updateProduct($categoryId, $productId, $position = null) {
		return parent::updateProduct($categoryId, $productId, $position);
	}

	/*
		Function: removeProduct

		Returns: boolean
	*/
	public function removeProduct($categoryId, $productId) {
		return parent::removeProduct($categoryId, $productId);
	}

	/*
		Function: getIdByUrlKey

		Returns: array
	*/
	public function getIdByUrlKey($url_key, $store_id = null) {
		$collection = Mage::getModel('catalog/category')->getCollection()->setStoreId($this->_getStoreId($store));
		$collection->addFieldToFilter('url_key', $url_key);
		$results = array();
		foreach ($collection as $category) {
			$results[] = $category->getId();
			//continue;
		}
		return $results;
	}

	/*
		Function: getSpecials

		Returns: array
	*/
	public function getSpecials($store = null, $cat_id = null) {
		set_time_limit( ini_get('max_execution_time')+180 );
		
		$store_id = Mage::app()->getStore($store)->getId();
		$write = Mage::getSingleton('core/resource')->getConnection('core_write');
		
		$entity_type_id = $write->fetchOne("
			SELECT `entity_type_id`
			FROM `eav_entity_type`
			WHERE `entity_type_code` = 'catalog_product'
			LIMIT 1
		");
		
		list($special_price_id, $special_price_type) = array_values($write->fetchRow("
			SELECT `attribute_id`, `backend_type`
			FROM `eav_attribute`
			WHERE `attribute_code` = 'special_price'
				AND `entity_type_id` = '{$entity_type_id}'
			LIMIT 1
		"));
		
		list($is_for_sale_id, $is_for_sale_type) = array_values($write->fetchRow("
			SELECT `attribute_id`, `backend_type`
			FROM `eav_attribute`
			WHERE `attribute_code` = 'bd_is_for_sale'
				AND `entity_type_id` = '{$entity_type_id}'
			LIMIT 1
		"));
		
		list($status_id, $status_type) = array_values($write->fetchRow("
			SELECT `attribute_id`, `backend_type`
			FROM `eav_attribute`
			WHERE `attribute_code` = 'status'
				AND `entity_type_id` = '{$entity_type_id}'
			LIMIT 1
		"));
		
		$sql = array('select'=>array(),'from'=>array(),'left_join'=>array(),'where'=>array());
		$sql['select'][] = "IF( parents.`parent_id` IS NOT NULL, parents.`parent_id`, special.`entity_id`) as entity_id";
		$sql['from'] = "`catalog_product_entity_{$special_price_type}` special";
		$sql['left_join'][] = "`catalog_product_entity_{$is_for_sale_type}` sale ON special.`entity_id` = sale.`entity_id`";
		$sql['left_join'][] = "`catalog_product_entity_{$status_type}` status ON special.`entity_id` = status.`entity_id`";
		$sql['left_join'][] = "`catalog_product_super_link` parents ON special.`entity_id` = parents.`product_id`";
		$sql['where'][] = "special.`attribute_id` = '{$special_price_id}'";
		$sql['where'][] = "(special.`store_id` = '{$store_id}' OR special.`store_id` = '0')";
		$sql['where'][] = "sale.`attribute_id` = '{$is_for_sale_id}'";
		$sql['where'][] = "sale.`value` = '1'";
		$sql['where'][] = "status.`attribute_id` = '{$status_id}'";
		$sql['where'][] = "status.`value` = '1'";
		
		$sql['select'] = implode(', ', $sql['select']);
		$sql['left_join'] = implode("\n\nLEFT JOIN ", $sql['left_join']);
		$sql['where'] = implode("\n\nAND ", $sql['where']);
		
		$query = "SELECT {$sql['select']}\nFROM {$sql['from']}\nLEFT JOIN {$sql['left_join']}\nWHERE {$sql['where']}";
		$products = $write->fetchAll($query);
		
		$product_ids = array();
		foreach( $products as $product ){
			$product_ids[] = $product['entity_id'];
		}
		
		$product_ids = array_unique($product_ids);
		return $product_ids;
	}
	
	public function associateProducts( $categoryId, $productIds, $store = null ){
		$effected_product_ids = array();
		$Product_API = new Communitas_Integrate_Model_Catalog_Product_Api();
//		$Configurable_API = new Communitas_Integrate_Model_Catalog_Product_Type_Configurable_Api();
		
		foreach( $productIds as $product_id ){
			$skip_product = false;
			$product = $this->_getProduct($product_id, $store);
			
			if (!$product->getId()) {
				continue;	## Product does not exist
			} else {
				$product_categories = $product->getCategoryIds();
				
				if( is_array($product_categories) && !in_array($categoryId,$product_categories) ){
					$product_categories[] = $categoryId;
				} elseif( !is_array($product_categories) ){
					$product_categories = array($categoryId);
				} else {
					$skip_product = true;
				}
/*				
				if( $product->getTypeId() == 'configurable' ){
					$children = $Configurable_API->getChildrenIds( $product->getId() );
					
					## Correct the children array
					if( is_array($children) && isset($children[0]) && is_array($children[0]) ){
						$children = $children[0];
					}
					
					$updated_children = $this->associateProducts( $categoryId, $children, $store );
					$effected_product_ids = array_merge($effected_product_ids, $updated_children);
				}
*/				
				if( !$skip_product ){
					$Product_API->update( $product->getId(), array('categories'=>$product_categories), $store );
					$effected_product_ids[] = $product->getId();
				} else {
					$effected_product_ids[] = $product->getId();
				}
			}
		}
		
		if( !empty($effected_product_ids) ){
			return $effected_product_ids;
		} else {
			return false;
		}
	}
	
	public function disassociateProducts( $categoryId, $productIds, $store = null ){
		$effected_product_ids = array();
		$Product_API = new Communitas_Integrate_Model_Catalog_Product_Api();
//		$Configurable_API = new Communitas_Integrate_Model_Catalog_Product_Type_Configurable_Api();
		
		foreach( $productIds as $product_id ){
			$skip_product = false;
			$product = $this->_getProduct($product_id, $store);
			
			if (!$product->getId()) {
				continue;	## Product does not exist
			} else {
				$product_categories = $product->getCategoryIds();
				
				if( is_array($product_categories) && in_array($categoryId,$product_categories) ){
					$key = array_search($categoryId,$product_categories);
					unset($product_categories[ $key ]);
				} else {
					$skip_product = true;
				}
/*				
				if( $product->getTypeId() == 'configurable' ){
					$children = $Configurable_API->getChildrenIds( $product->getId() );
					
					## Correct the children array
					if( is_array($children) && isset($children[0]) && is_array($children[0]) ){
						$children = $children[0];
					}
					
					$updated_children = $this->disassociateProducts( $categoryId, $children, $store );
					$effected_product_ids = array_merge($effected_product_ids, $updated_children);
				}
*/				
				if( !$skip_product ){
					$Product_API->update( $product->getId(), array('categories'=>$product_categories), $store );
					$effected_product_ids[] = $product->getId();
				} else {
					$effected_product_ids[] = $product->getId();
				}
			}
		}
		
		if( !empty($effected_product_ids) ){
			return $effected_product_ids;
		} else {
			return false;
		}
	}
}
